/**
 * Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * For the applicable distribution terms see the license text file included in
 * the distribution.
 */


#include <qglbuilder.h>
#include <btBulletDynamicsCommon.h>
#include "blackhole.h"

/*!
  \class BlackHole
  \brief Representes a black hole. Constructed from a Qt3D plane and Bullet
         plane shape. Static Bullet object colliding with Ball objects.
*/


/*!
  Constructor, creates Qt3D plane object and attaches static Bullet plane
  collision shape to it. Collides with Ball.
*/
BlackHole::BlackHole(btDiscreteDynamicsWorld *world,
                     const QVector3D &planeVector,
                     qreal planeConstant,
                     QObject *parent)
    : GameObject(world, QVector3D(), QQuaternion(), parent)
{
    m_GameObjectType = BLACK_HOLE;

    {
        QGLBuilder builder;
        builder.addPane(QSizeF(85.0f, 80.0f));
        m_BlackHoleBack = builder.finalizedSceneNode();
        m_BlackHoleBack->setPosition(QVector3D(0, 0, planeConstant));
        m_SceneNode = m_BlackHoleBack;
    }

#ifdef Q_WS_WIN
    // Black hole whirl effect, available only on windows
    {
        QGLBuilder builder;
        builder.addPane(QSizeF(120, 120));
        m_BlackHoleMid = builder.finalizedSceneNode();
        m_BlackHoleMid->setPosition(QVector3D(0, 0, 2));
        m_SceneNode->addNode(m_BlackHoleMid);
    }

    {
        QGLBuilder builder;
        builder.addPane(QSizeF(70, 70));
        m_BlackHoleFront = builder.finalizedSceneNode();
        m_BlackHoleFront->setPosition(QVector3D(0, 0, 2));
        m_BlackHoleMid->addNode(m_BlackHoleFront);
    }
#endif

    btVector3 pv = btVector3(planeVector.x(), planeVector.y(), planeVector.z());
    btCollisionShape *planeShape = new btStaticPlaneShape(pv, planeConstant);
    btRigidBody::btRigidBodyConstructionInfo planeRigidBodyCI(
                0, this, planeShape, btVector3(0, 0, 0));

    m_Body = new btRigidBody(planeRigidBodyCI);
    m_Body->setUserPointer(this);

    world->addRigidBody(m_Body, COL_BLACK_HOLE, COL_BALL);
}


/*!
  Sets the materials for the black hole. The black hole is animated by adding
  two layer of rotating planes of top of the back plane to make the black hole
  whirl.
*/
void BlackHole::setMaterials(QGLMaterialCollection *materialCollection,
                             int backMaterialIndex,
                             int frontMaterialIndex)
{
    m_BlackHoleBack->setPalette(materialCollection);
    m_BlackHoleBack->setMaterialIndex(backMaterialIndex);
    m_BlackHoleBack->setEffect(QGL::FlatDecalTexture2D);

#ifdef Q_WS_WIN
    // Black hole whirl only available on windows
    m_BlackHoleMid->setPalette(materialCollection);
    m_BlackHoleMid->setMaterialIndex(frontMaterialIndex);
    m_BlackHoleMid->setEffect(QGL::LitModulateTexture2D);

    m_BlackHoleFront->setPalette(materialCollection);
    m_BlackHoleFront->setMaterialIndex(frontMaterialIndex);
    m_BlackHoleFront->setEffect(QGL::LitModulateTexture2D);
#else
    Q_UNUSED (frontMaterialIndex);
#endif
}


/*!
  Rotates the black hole.
*/
void BlackHole::rotateBlackHole(int relTime)
{
#ifdef Q_WS_WIN
    qreal rotate = relTime * 1.0f / 200.0f;

    QMatrix4x4 mat = m_BlackHoleMid->localTransform();
    mat.rotate(-rotate, 0, 0, 1);
    m_BlackHoleMid->setLocalTransform(mat);

    mat = m_BlackHoleFront->localTransform();
    mat.rotate(-rotate * 1.35, 0, 0, 1);

    m_BlackHoleFront->setLocalTransform(mat);
#else
    Q_UNUSED(relTime);
#endif
}


/*!
  Draws the black hole.
*/
void BlackHole::draw(QGLPainter *painter)
{
#ifdef Q_WS_WIN
    glEnable(GL_BLEND);
    GameObject::draw(painter);
    glDisable(GL_BLEND);
#else
    GameObject::draw(painter);
#endif
}
